Use case: SDIO extended DMA transfer

The extended DMA transfer uses interrupts to handle transfer completion and errors. The sequence and APIs remain mostly unchanged between HAL1 and HAL2, with only changes in the callback registration and handling.

An SDIO Wi‑Fi device may expose multiple functions where user_io_func_nbr selects the Wi‑Fi function; an extended transfer could then transfer a TCP/IP packet in the Wi‑Fi function.

HAL1

HAL2

Extended DMA transfer uses HAL_SDIO_WriteExtended_DMA() and HAL_SDIO_ReadExtended_DMA() for non-blocking I/O. Transfer completion is reported via separate TX/RX callbacks registered with HAL_SDIO_RegisterCallback().

Extended DMA transfer sequence is mostly unchanged, but callback registration is unified through HAL_SDIO_RegisterXferCpltCallback(), registering only one transfer callback which delivers both TX and RX events using an event parameter.

@startuml
hide footbox
participant "User Application" as part1
participant "HAL SDIO" as part2
participant "NVIC" as part3
activate part1
activate part2

group Register transfer complete callbacks
part1->part2 : HAL_SDIO_RegisterCallback(&hsdio, HAL_SDIO_TX_CPLT_CB_ID, USER_SDIO_TxCpltCallback)
part2 --> part1
part1->part2 : HAL_SDIO_RegisterCallback(&hsdio, HAL_SDIO_RX_CPLT_CB_ID, USER_SDIO_RxCpltCallback)
part2 --> part1
end

group I/O Operation process (Extended DMA)
part1->part2 : HAL_SDIO_WriteExtended_DMA()
part2-->part1
part3 -> part2 : HAL_SDIO_IRQHandler()
part2 -> part1 : USER_SDIO_TxCpltCallback()
part1->part2 : HAL_SDIO_ReadExtended_DMA()
part2-->part1
part3 -> part2 : HAL_SDIO_IRQHandler()
part2 -> part1 : USER_SDIO_RxCpltCallback()
end
@enduml

Code Snippet

HAL1

HAL2

/* Register the Tx and Rx Transfer complete callbacks */
HAL_SDIO_RegisterCallback(&hsdio,
                          HAL_SDIO_TX_CPLT_CB_ID,
                          USER_SDIO_TxCpltCallback);
HAL_SDIO_RegisterCallback(&hsdio,
                          HAL_SDIO_RX_CPLT_CB_ID,
                          USER_SDIO_RxCpltCallback);

/* Write BufferSize bytes to function user_io_func_nbr
    at address IoAddress using Extended DMA */
HAL_SDIO_WriteExtended_DMA(&hsdio,
                           user_io_func_nbr,
                           Write_IoAddress,
                           Buffer_Tx,
                           BufferSize);
/* Wait for the Writing process to complete */
while (sdiotransfertx == 0)
{}
 /* Read BufferSize bytes from function user_io_func_nbr
     at address IoAddress using Extended DMA */
 HAL_SDIO_ReadExtended_DMA(&hsdio,
                           user_io_func_nbr,
                           ReadIoAddress,
                           Buffer_Rx,
                           BufferSize);
/* Wait for the Reading process to complete */
while (sdiotransferrx == 0)
{}


void USER_SDIO_TxCpltCallback(SDIO_HandleTypeDef *hsdio) {
    sdiotransfertx = 1;
}

void USER_SDIO_RxCpltCallback(SDIO_HandleTypeDef *hsdio) {
    sdiotransferrx = 1;
}
/* Register the Tx and Rx Transfer complete callbacks */
HAL_SDIO_RegisterXferCpltCallback(&hsdio,
                                  USER_SDIO_XferCallback);





/* Write BufferSize bytes to function user_io_func_nbr
    at address IoAddress using Extended DMA */
HAL_SDIO_WriteExtended_DMA(&hsdio,
                           user_io_func_nbr,
                           Write_IoAddress,
                           Buffer_Tx,
                           BufferSize);
/* Wait for the Writing process to complete */
while (sdiotransfertx == 0)
{}
/* Read BufferSize bytes from function user_io_func_nbr
    at address IoAddress using Extended DMA */
HAL_SDIO_ReadExtended_DMA(&hsdio,
                          user_io_func_nbr,
                          Read_IoAddress,
                          Buffer_Rx,
                          BufferSize);
/* Wait for the Reading process to complete */
while (sdiotransferrx == 0)
{}


void USER_SDIO_XferCallback(hal_sdio_handle_t *hsdio,
                            hal_sdio_event_cb_t cb_event) {
    switch (cb_event) {
        case HAL_SDIO_EVENT_CB_TX_CPLT:
        sdiotransfertx = 1;
        break;
        case HAL_SDIO_EVENT_CB_RX_CPLT:
        sdiotransferrx = 1;
        break;
        default: break;
    }
}